/*
* ============================================================================
*  Name        : example_009.cpp
*  Part of     : Finite state machine examples
*  Description : Message exchange between two state machines
*  Version     : %version: %
*  
*
* ============================================================================
*/
#include "example_009.h"
#include "example_009.hxx" // State machine source code is here
#include "main.h"

extern const char* Input_src;

/**
 * @file example_009.cpp
 *
 * @details
 *
 * @ingroup StateMachineExamples
 */
using namespace sea_examples;

const int width = 80;

// ----------------------------------------------------------------------------
// Example of user input processing. Pressing Righ and Left arrow key moves the 
// 'snake'. Esc finishes state machine.
// ----------------------------------------------------------------------------
void sea_examples::launch_example_009( )
{
    SEA_TRACE_ENTRY( );

    {
        sea::ref< Snake > le;
        le << NEW Snake( 20 );

        le->create( 0, Snake_src );
        le->start( );

        sea::ref< Input > input;
        input << NEW Input( le.get( ), le->Ev_Ext_Key( ) );

        input->create( 0, Input_src );
        input->start( );
        input->set_dispatcher_priority( Higher );

        le->wait_manager_to_finish( );
    }
    Engine::terminate( );
}

// ----------------------------------------------------------------------------

Snake::Snake( int aPosition ) : 
    StateMachine( STATEMACHINE_NAME ), 
        m_position( aPosition % width ) { }

// ----------------------------------------------------------------------------

ACT_IMPL( Snake, check_input )
{
    SEA_UNUSED_PARAM( );

    if ( event( )->data< int >( ) == 0x4d )
    {
        push_event( Ev_Int_MoveRight( ) );
    }
    if ( event( )->data< int >( ) == 0x4b )
    {
        push_event( Ev_Int_MoveLeft( ) );
    }

    if ( event( )->data< int >( ) == 0x1B )
    {
        push_event( terminate_event_id( ) );
    }
}

// ----------------------------------------------------------------------------

ACT_IMPL( Snake, move_right )
{
    SEA_UNUSED_PARAM( );

    if ( m_position > 80 )
    {
        m_position = width;
    }
    else
    {
        ++m_position;
    }
}

// ----------------------------------------------------------------------------

ACT_IMPL( Snake, move_left )
{
    SEA_UNUSED_PARAM( );

    if( m_position == 0 )
    {
        m_position = width;
    }
    else
    {
        --m_position;
    }
}

// ----------------------------------------------------------------------------

ACT_IMPL( Snake, draw )
{
    SEA_UNUSED_PARAM( );
    char buffer[ width + 1 ];
    memset( buffer, ' ', width );
    buffer[ m_position ] = '$';
    buffer[ width ] = 0;
    SEA_TRACE( buffer );
}

// ----------------------------------------------------------------------------
